#include "qemu/osdep.h"
#include "hw/misc/localbus.h"
#include "qemu/module.h"

LBCBus *localbus_init_bus(DeviceState *parent, const char *name)
{
    LBCBus *bus;
    bus = LBC_BUS(qbus_create(TYPE_LBC_BUS, parent, name));
    //todo：如果要创建从设备，那么也需要管理挂载在该总线上的i2c从设备
    //todo:虚拟机状态注册,用于支持热迁移时自动保存/恢复总线状态
    return bus;
}

static const TypeInfo localbus_bus_info = {
    .name = TYPE_LBC_BUS,
    .parent = TYPE_BUS,
    .instance_size = sizeof(LBCBus),
};

static void localbus_slave_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *k = DEVICE_CLASS(klass);
    set_bit(DEVICE_CATEGORY_MISC, k->categories);
    k->bus_type = TYPE_LBC_BUS;
}

int localbus_send(LBCBus *bus, hwaddr addr, uint32_t data)
{
    LBCSlaveClass *sc;
    LBCSlave *s;
    int ret = 0;

    if (bus == NULL) {
        return -1;
    }

    s = bus->current_devs;
    if (s == NULL) {
        return -1;
    }

    sc = LBC_SLAVE_GET_CLASS(s);
    if (sc->send) {
        ret = sc->send(s, addr, data);
    } else {
        ret = -1;
    }

    return ret;
}

uint32_t localbus_recv(LBCBus *bus, hwaddr addr)
{
    LBCSlaveClass *sc;
    LBCSlave *s;
    uint32_t data = 0xffffffff;

    if (bus == NULL) {
        return -1;
    }

    s = bus->current_devs;
    if (s == NULL) {
        return -1;
    }

    sc = LBC_SLAVE_GET_CLASS(s);
    if (sc->recv) {
        data = sc->recv(s, addr);
    }
    return data;
}

static const TypeInfo localbus_slave_type_info = {
    .name = TYPE_LBC_SLAVE,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(LBCSlave),
    .abstract = true,
    .class_size = sizeof(LBCSlaveClass),
    .class_init = localbus_slave_class_init,
};

static void localbus_register_types(void)
{
    type_register_static(&localbus_bus_info);
    type_register_static(&localbus_slave_type_info);
}

type_init(localbus_register_types)